package cn.imvc.app.models;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Service;

import cn.imvc.app.domains.FundFlowType;
import cn.imvc.app.domains.OrderState;
import cn.imvc.app.entities.GoodsOrder;
import cn.imvc.app.entities.Orders;
import cn.imvc.app.entities.StorageOrder;
import cn.imvc.app.repositories.GoodsOrderRepository;
import cn.imvc.core.ModelUtil;
import cn.imvc.data.domain.ViewRequest;
import cn.imvc.service.api.GoodsService;

@Service("goodsOrderModel")
public class GoodsOrderModelImpl implements GoodsOrderModel {
	@Autowired
	GoodsOrderRepository goodsOrderRepository;
	@Autowired
	GoodsService goodsService; 			//dubbo公共接口
	@Autowired
	AccountModel accountModel;
	@Autowired
	OrdersModel ordersModel;
	
	GoodsOrder goodsOrder;

	public LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> getRequestMap() {
		// TODO Auto-generated method stub
		return null;
	}

	public Page<GoodsOrder> find(ViewRequest viewRequest) {
		return goodsOrderRepository.findAll("o","GoodsOrder o",ModelUtil.OrderByIdDesc(viewRequest));
	}

	public GoodsOrder get(int id) {
		return goodsOrderRepository.findOne(id);
	}

	public GoodsOrder save(GoodsOrder goodsOrder) {
		return goodsOrderRepository.save(goodsOrder);
	}

	public GoodsOrder update(GoodsOrder goodsOrder) {
		goodsOrder.setUpdatedAt(new Date());
		return goodsOrderRepository.saveAndFlush(goodsOrder);
	}

	public void delete(int id) {
		// TODO Auto-generated method stub

	}

	public void deleteBatch(int[] ids) {
		// TODO Auto-generated method stub

	}
	
	/**
	 * 获取所有订单
	 */
	public List<GoodsOrder> findAll() {
		return goodsOrderRepository.findAll();
	}
	
	/**
	 * 设为发货失败，返还库存和金额
	 * @param id
	 * @return
	 */
	public boolean updateDeliveryFailed(int id) {
		goodsOrder = get(id);
		boolean state = false;
		if(goodsOrder.getState() == OrderState.Delivery.getValue()){
			goodsOrder.setState(OrderState.DeliveryFailed.getValue());
			goodsOrder.setRefundAmount(goodsOrder.getPrice()*goodsOrder.getNum());
			update(goodsOrder);
			
			List<Integer[]> skuInfos = new ArrayList<Integer[]>();
			//返还库存
			Integer[] skuInfo = new Integer[3];
			skuInfo[0] = goodsOrder.getGoodsSku().getId();
			skuInfo[1] = -goodsOrder.getNum();
			skuInfo[2] = goodsOrder.getId();
			skuInfos.add(skuInfo);
			goodsService.retryBatchUpdateGoodsInventory(skuInfos, false);
			
			Orders orderTmp = ordersModel.get(goodsOrder.getOrder().getId());
			int freightAmount = ordersModel.calculateFreightAmount(orderTmp);
			int returnFreightAmount = 0; 
			if(orderTmp.getFreightAmount() > freightAmount){
				returnFreightAmount = orderTmp.getFreightAmount() - freightAmount;
				orderTmp.setFreightAmount(freightAmount);
			}
			orderTmp.setRefundAmount(goodsOrder.getRefundAmount()+returnFreightAmount);
			ordersModel.update(orderTmp);
			//5、退款操作（除了商品金额以外，如果需要减运费，还应退还运费费用）
			accountModel.retryRefundAccount(goodsOrder.getMember().getId(), orderTmp.getRefundAmount(), FundFlowType.Refund.getValue(),String.valueOf(goodsOrder.getCode()));
			state = true;
		}
		return state;
	}

	public boolean updateSyncState(StorageOrder storageOrder) {
		Set<GoodsOrder> storageOrders = storageOrder.getGoodsOrder();
		Iterator<GoodsOrder> iterator = storageOrders.iterator();
		while (iterator.hasNext()) {
			GoodsOrder goodsOrder = (GoodsOrder) iterator.next();
			GoodsOrder goodsOrderTmp = get(goodsOrder.getId());
			goodsOrderTmp.setState(storageOrder.getState());
			update(goodsOrderTmp);
		}
		return true;
	}

	@Override
	public List<GoodsOrder> findByState(Byte value) {
		return goodsOrderRepository.findByState(value);
	}

	@Override
	public List<GoodsOrder> findByOrder(Orders order) {
		return goodsOrderRepository.findByOrder(order);
	}

	@Override
	public boolean updateSyncStateByPreState(StorageOrder storageOrder, Byte state) {
		Set<GoodsOrder> storageOrders = storageOrder.getGoodsOrder();
		Iterator<GoodsOrder> iterator = storageOrders.iterator();
		while (iterator.hasNext()) {
			GoodsOrder goodsOrder = (GoodsOrder) iterator.next();
			GoodsOrder goodsOrderTmp = get(goodsOrder.getId());
			if(goodsOrderTmp.getState() == state){
				goodsOrderTmp.setState(storageOrder.getState());
				update(goodsOrderTmp);
			}
		}
		return true;
	}

	@Override
	public List<GoodsOrder> findByStateAndCreatedAtLessThan(Byte value, Date time) {
		return goodsOrderRepository.findByStateAndCreatedAtLessThan(value,time);
	}

}
